<template>
	<div class="home">
		<section class="operation">
			<!-- 组件 -->
			<div class="operation-left">
				<el-scrollbar height="100%">
					<sliderassembly :pointer="pointer" />
				</el-scrollbar>
			</div>

			<!-- 手机 -->
			<div class="phone cursor" @click.stop="currentPage">
				<section class="phoneAll" ref="imageTofile" id="imageTofile">
					<img :src="PhoneTop" alt="" class="statusBar" />
					<!-- 主体内容 -->

					<section class="phone-container" @drop="drop($event)" @dragover="allowDrop($event)" @dragleave="dragleaves()" :style="backgroud">
						<!-- 动态组件 -->
						<vuedraggable
							:class="pointer.show ? 'pointer-events' : ''"
							:list="pageComponents"
							item-key="index"
							:forceFallback="true"
							:animation="200"
						>
							<template #item="{ element, index }">
								<component
									:is="element.component"
									:datas="element.setStyle"
									:style="{
										border: element.active && deleShow ? '2px solid #155bd4' : '',
									}"
									@click.stop="activeComponent(element, index)"
									class="componentsClass"
									:data-type="element.type"
									v-if="element.type != 'pageSetting'"
								>
									<template #deles>
										<div v-show="deleShow" class="deles" @click.stop="deleteObj(index)">
											<!-- 删除组件 -->
											<span class="iconfont icon-sanjiaoxingzuo"></span>
											{{ element.text }}
											<van-icon name="delete" />
										</div>
									</template>
								</component>
							</template>
						</vuedraggable>
					</section>

					<!-- 手机高度 -->
					<div class="phoneSize">iPhone 15手机高度</div>

					<!-- 底部 -->
				</section>
				<!-- 底部 -->
			</div>

			<!-- 右侧工具栏 -->
			<div class="decorateAll">
				<div class="decorateAll-content">
					<!-- <el-scrollbar height="100%"> -->
					<!-- 页面设置 -->

					<!-- 动态组件 -->
					<component :is="rightcom" :datas="currentproperties" v-if="rightcom != ''" />
					<!-- </el-scrollbar> -->
				</div>
			</div>
		</section>
	</div>
</template>

<script setup lang="ts">
import utils from '/@/utils/decorate/index'; // 方法类
import componentProperties from '/@/utils/decorate/componentProperties'; // 组件数据
import { reactive, toRefs, onMounted, computed } from 'vue';
import { ElMessage } from 'element-plus';
import vuedraggable from 'vuedraggable'; //拖拽组件
import messageUtils from '/@/utils/messageUtils';
import { decorationApi } from '/@/api/shop/decoration/index';
import PhoneTop from '/@/assets/decoration/images/phoneTop.png';
import { STATIC_URL } from '/@/utils/config';
// 页面数据
const datas = reactive({
	templateId: String,
	id: null, //当前页面id
	pageComponents: [], //页面组件
});

/**
 * 切换组件位置  用于组件管理中删除功能
 *
 * @param {Object} res 组件切换后返回的位置
 */
const componenmanagement = (res: any) => {
	console.log('切换组件  res: ', res);
	datas.pageComponents = res;
};

const backgroud = computed(() => {
	const pageSetting = datas.pageComponents.find((e) => e.type === 'pageSetting');
	// console.log('pageSetting: ', pageSetting);
	if (pageSetting) {
		return {
			'background-color': pageSetting.setStyle.background.bgColor,
			'background-image': `url(${STATIC_URL}${pageSetting.setStyle.background.bgImg})`,
		};
	}
});

// 选择组件数据
const choose = reactive({
	deleShow: true, // 删除标签显示
	index: '', // 当前选中的index
	rightcom: '', // 右侧组件切换
	currentproperties: null, // 当前属性  默认：页面设置
	offsetY: 0, //记录上一次距离父元素高度
	onlyOne: ['1-5', '1-16'], // 只能存在一个的组件(组件的type)
	pointer: { show: false }, // 穿透
});

/**
 * 选择组件
 *
 * @param {Object} res 当前组件对象
 */
const activeComponent = (res: any, index: any) => {
	choose.index = index;
	/* 切换组件 */
	choose.rightcom = res.style;
	/* 丢样式 */
	choose.currentproperties = res.setStyle;

	/* 替换 */
	datas.pageComponents.forEach((res) => {
		/* 修改选中 */
		if (res.active === true) res.active = false;
	});
	/* 选中样式 */
	res.active = true;
	console.log('当前选中组件：', res);
};

/**
 * 删除组件
 *
 * @param {Number} index 当前组件index
 */
const deleteObj = (index: number) => {
	datas.pageComponents.splice(index, 1);
	if (choose.index === index) choose.rightcom = '';
	if (index < choose.index) choose.index = choose.index - 1;
};

/**
 * 当将元素或文本选择拖动到有效放置目标（每几百毫秒）上时，会触发此事件
 *
 * @param {Object} event event对象
 */
const allowDrop = (event: any) => {
	// console.log("allow drop : ", event)
	//阻止浏览器的默认事件
	event.preventDefault();

	/* 获取鼠标高度 */
	let eventoffset = event.offsetY;

	/* 如果没有移动不触发事件减少损耗 */
	if (choose.offsetY === eventoffset) return;
	else choose.offsetY = eventoffset;

	/* 获取组件 */
	const childrenObject = event.target.children[0];

	// 一个以上的组件计算
	if (datas.pageComponents.length - 1 > 0) {
		// console.log("start datas.pageComponents.length: ", datas.pageComponents.length)
		/* 如果只有一个组件并且第一个是提示组件直接返回 */
		if (datas.pageComponents.length === 1 && datas.pageComponents[0].type === 0) return;

		/* 如果鼠标的高度小于第一个的一半直接放到第一个 */
		if (eventoffset < childrenObject.children[0].clientHeight / 2) {
			/* 如果第一个是提示组件直接返回 */
			if (datas.pageComponents[0].type === 0) return;

			/* 删除提示组件 */
			datas.pageComponents = datas.pageComponents.filter((res) => res.component !== 'placementarea');

			/* 最后面添加提示组件 */
			datas.pageComponents.unshift({
				component: 'placementarea',
				type: 0,
			});

			console.log('end1 datas.pageComponents: ', datas.pageComponents.length);
			return;
		}

		/* 记录距离父元素高度 */
		const childOff = childrenObject.offsetTop;

		/* 鼠标在所有组件下面 */
		if (
			eventoffset > childrenObject.clientHeight ||
			childrenObject.lastChild.offsetTop - childOff + childrenObject.lastChild.clientHeight / 2 < eventoffset
		) {
			/* 最后一个组件是提示组件返回 */
			if (datas.pageComponents[datas.pageComponents.length - 1].type === 0) return;

			/* 清除提示组件 */
			datas.pageComponents = datas.pageComponents.filter((res) => res.component !== 'placementarea');

			/* 最后一个不是提示组件添加 */
			datas.pageComponents.push({
				component: 'placementarea',
				type: 0,
			});
			console.log('end2==== datas.pageComponents: ', datas.pageComponents);
			return;
		}

		const childrens = childrenObject.children;

		/* 在两个组件中间，插入 */
		for (let i = 0, l = childrens.length; i < l; i++) {
			const childoffset = childrens[i].offsetTop - childOff;

			if (childoffset + childrens[i].clientHeight / 2 > event.offsetY) {
				/* 如果是提示组件直接返回 */
				if (datas.pageComponents[i].type === 0) break;

				if (datas.pageComponents[i - 1].type === 0) break;

				/* 清除提示组件 */
				datas.pageComponents = datas.pageComponents.filter((res) => res.component !== 'placementarea');

				datas.pageComponents.splice(i, 0, {
					component: 'placementarea',
					type: 0,
				});
				break;
			} else if (childoffset + childrens[i].clientHeight > event.offsetY) {
				if (datas.pageComponents[i].type === 0) break;

				if (!datas.pageComponents[i + 1] || datas.pageComponents[i + 1].type === 0) break;

				datas.pageComponents = datas.pageComponents.filter((res) => res.component !== 'placementarea');

				datas.pageComponents.splice(i, 0, {
					component: 'placementarea',
					type: 0,
				});

				break;
			}
		}
		console.log('end3 datas.pageComponents: ', datas.pageComponents.length);
	} else {
		console.log('0个组件.....');
		/* 一个组件都没有直接push */
		datas.pageComponents.push({
			component: 'placementarea',
			type: 0,
		});
	}
};

/**
 * 当在有效放置目标上放置元素或选择文本时触发此事件
 *
 * @param {Object} event event对象
 */
const drop = (event) => {
	/* 获取数据 */
	let data = utils.deepClone(componentProperties.get(event.dataTransfer.getData('componentName')));

	/* 查询是否只能存在一个的组件且在第一个 */
	let someOne = datas.pageComponents.some((item, index) => {
		return item.component === 'placementarea' && index === 0 && choose.onlyOne.includes(data.type);
	});
	if (someOne) {
		ElMessage.info('固定位置的组件(如: 底部导航、悬浮)不能放在第一个!');
		/* 删除提示组件 */
		dragleaves();
		return;
	}

	/* 查询是否只能存在一个的组件 */
	let someResult = datas.pageComponents.some((item) => {
		console.log(item.component, '--------------item.component');
		return choose.onlyOne.includes(item.type) && item.component === event.dataTransfer.getData('componentName');
	});
	if (someResult) {
		ElMessage.info('当前组件只能添加一个!');
		/* 删除提示组件 */
		dragleaves();
		return;
	}

	// console.log("替换内容 : ", datas.pageComponents)
	/* 替换 这里替换 placementarea 为正常的 数据 ...*/
	datas.pageComponents.forEach((res, index) => {
		/* 修改选中 */
		if (res.active === true) res.active = false;
		/* 替换提示 */
		choose.index = index;
		if (res.component === 'placementarea') datas.pageComponents[index] = data;
	});

	/* 切换组件 */
	choose.rightcom = data.style;
	/* 丢样式 */
	choose.currentproperties = data.setStyle;
};

/**
 * 当拖动的元素或文本选择离开有效的放置目标时，会触发此事件
 *
 * @param {Object} event event对象
 */
const dragleaves = () => {
	console.log('drag leaves ', datas.pageComponents);
	/* 删除提示组件 */
	datas.pageComponents = datas.pageComponents.filter((res) => res.component !== 'placementarea');
};

let saveInfo = async () => {
	console.log('shop home 保存信息');
	try {
		await decorationApi().createHomeComponents({
			id: datas.templateId,
			homeComponents: datas.pageComponents,
		});
		messageUtils().success('操作成功');
	} catch (e) {
		console.error(e);
		messageUtils().error('创建主页模版失败，请稍后重试');
	}
};

onMounted(() => {});

const init = (templateId, homeTemplate) => {
	console.log('homeTemplate init templateId: ', templateId);

	console.log('homeTemplate init homeTemplate: ', homeTemplate);
	datas.templateId = templateId;

	if (homeTemplate) {
		console.log('设置 baseTemplate');
		datas.pageComponents = homeTemplate;
		console.log('end 设置 baseTemplate: ', datas.pageComponents);
		datas.pageComponents.forEach((res) => {
			if (res.active === true) {
				res.active = false;
				choose.rightcom = res.style;
				/* 丢样式 */
				choose.currentproperties = res.setStyle;
			}

			if (res.type === 'pageSetting') {
				// res.active = true;
				choose.rightcom = res.style;
				/* 丢样式 */
				choose.currentproperties = res.setStyle;
			}
		});
	} else {
		let data = utils.deepClone(componentProperties.get('pageSetting'));
		datas.pageComponents.splice(0, 0, data);
		console.log('不存在导航');
		choose.rightcom = 'pageSetting';
		choose.currentproperties = data.setStyle;
	}
};

const currentPage = () => {
	console.log('currentPage');
	let data = utils.deepClone(componentProperties.get('pageSetting'));
	const navigation = datas.pageComponents.find((e) => e.style === 'pageSetting');
	if (navigation) {
		console.log('配置存在');
		datas.pageComponents.forEach((res, index) => {
			if (res.active === true) res.active = false;
			if (res.type === 'pageSetting') {
				// res.active = true;
				choose.rightcom = res.style;
				/* 丢样式 */
				choose.currentproperties = res.setStyle;
			}
		});
	} else {
		datas.pageComponents.splice(0, 0, data);
		console.log('不存在导航');
		datas.pageComponents.forEach((res, index) => {
			if (res.active === true) res.active = false;
			console.log('数据: ', res);
		});
		choose.rightcom = 'pageSetting';
		choose.currentproperties = data.setStyle;
	}
};

defineExpose({ saveInfo, init });

const { pageComponents } = toRefs(datas);
const { deleShow, rightcom, currentproperties, pointer } = toRefs(choose);
</script>
<style scoped lang="scss">
.pointer-events {
	pointer-events: none;
}

.home {
	width: 100%;
	height: 100%;
	overflow: hidden;
	/* 删除组件 */
	.deles {
		position: absolute;
		min-width: 80px;
		text-align: center;
		line-height: 25px;
		background: #fff;
		height: 25px;
		font-size: 12px;
		left: 103%;
		top: 50%;
		transform: translateY(-50%);

		.icon-sanjiaoxingzuo {
			position: absolute;
			left: -11px;
			color: #fff;
			font-size: 12px;
			top: 50%;
			transform: translateY(-50%);
		}

		&:hover {
			i {
				display: block;
				position: absolute;
				left: 0;
				font-size: 16px;
				top: 0;
				text-align: center;
				line-height: 25px;
				width: 100%;
				color: #fff;
				height: 100%;
				z-index: 10;
				background: rgba(0, 0, 0, 0.5);
			}

			.icon-sanjiaoxingzuo {
				color: rgba(0, 0, 0, 0.5);
			}
		}

		i {
			display: none;
		}
	}

	/* 按钮集合 */

	/* 操作主体 */
	.operation {
		width: 100%;
		height: 100%;
		display: flex;
		flex-direction: row;
		justify-content: space-between;
		background: #f7f8fa;
	}

	.operation-left {
		height: 100%;
		overflow: hidden;
		//overflow-x: hidden;
	}

	/* 手机 */
	.phone {
		//width: 55%;
		flex: 1;
		height: 100%;
		overflow-y: scroll;
		display: flex;
		justify-content: center;
		background: #f7f8fa;

		&::-webkit-scrollbar {
			width: 6px;
		}

		/* 手机样式 */
		.phoneAll {
			width: 375px;
			// min-height: 760px;
			box-shadow: 0 0 14px 0 rgba(0, 0, 0, 0.1);
			position: relative;

			/* 手机高度 */
			.phoneSize {
				position: absolute;
				left: -137px;
				top: 640px;
				font-size: 12px;
				color: #a2a2a2;
				border-bottom: 1px solid #dedede;
				width: 130px;
				height: 21px;
				line-height: 21px;
			}

			/* 状态栏 */
			.statusBar {
				width: 100%;
				display: block;
			}

			/* 主体内容 */
			.phone-container {
				min-height: 603px;
				box-sizing: border-box;
				cursor: pointer;
				width: 100%;
				position: relative;
				background-repeat: no-repeat;
				background-size: 100% 100%;

				.componentsClass {
					border: 1px solid #fff;

					&:hover {
						border: 1px dashed #155bd4;
					}
				}
			}
		}
	}

	/* 右侧工具栏 */
	.decorateAll {
		width: 376px;
		height: 100%;
		position: relative;
		padding: 0 12px;
		background: #fff;
		overflow-y: scroll;
		overflow-x: hidden;
		// overflow: hidden;

		// &::-webkit-scrollbar {
		// 	width: 1px;
		// }

		// &::-webkit-scrollbar-thumb {
		// 	background-color: #155bd4;
		// }
	}

	.decorateAll-content {
		height: 100%;

		// border-left: 1px solid #fff;
		// border-right: 1px solid #fff;
	}

	/* 页面设置tab */
	.decorateTab {
		position: fixed;
		display: flex;
		right: 380px;
		top: 115px;
		flex-direction: column;

		span {
			background-color: #fff;
			box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
			border-radius: 2px;
			width: 94px;
			height: 32px;
			display: inline-block;
			text-align: center;
			line-height: 32px;
			margin-bottom: 12px;
			transition: all 0.8s;
			cursor: pointer;

			&.active {
				background-color: #155bd4;
				color: #fff;
			}

			/* 图标 */
			i {
				font-size: 12px;
				margin-right: 5px;
			}
		}
	}
}

/* 动画 */
.decorateAnima-enter-active {
	transition: all 1.5s ease;
}

.decorateAnima-leave-active {
	transition: all 1.5s ease;
}

.decorateAnima-enter {
	transform: translate(8px, 8px);
	opacity: 0;
}

.decorateAnima-leave-to {
	transform: translate(8px, 8px);
	opacity: 0;
}
</style>
